import {
    AfterViewInit,
    Component,
    ComponentFactoryResolver,
    ComponentRef,
    Input,
    OnDestroy,
    OnInit,
    ViewChild
} from '@angular/core';
import Map from 'ol/Map';
import {unByKey} from 'ol/Observable.js';
import {InteractionCompnent} from './interface/interaction-compnent.interface';
import {UtilItem} from './interface/util-item.interface';
import {MapUtilsService} from './map-utils/map-utils.service';
import {UtilDirective} from './directive/util.directive';
import {UtilComponent} from './interface/util-component.interface';

@Component({
    selector: 'kylin-map-interaction',
    templateUrl: './map-interaction.component.html',
    styleUrls: ['./map-interaction.component.less']
})
export class MapInteractionComponent implements OnInit, OnDestroy {
    utils: Array<UtilItem> = []; // 地图操作按钮组
    @Input() map: Map;

    @Input() set operationData(val: any) {
        const operation = val['operation'];
        if (operation === 'layerEdit') {
            this.utilsVisible = true;
            if (val['layerId']) {
                this.insertUtilContent(this.utils.find(item => item.label === '绘制'), {drawLayerId: val['layerId']});
            }
        }
    };

    utilsVisible = false;
    @ViewChild(UtilDirective, {static: true}) utilHost: UtilDirective;
    currentUtil: UtilItem;
    renderFirst = true;
    listenerList = new Array<any>();

    constructor(private componentFactoryResolver: ComponentFactoryResolver, private utilsSvc: MapUtilsService) {
        this.utils = this.utilsSvc.getUtils();
    }

    ngOnInit() {
        if (this.map) {
            const targetId = this.map.getTarget();
            document.getElementById(targetId as string).style.position = 'relative';
            const renderListener = this.map.on('rendercomplete', this.reSetSize);
            this.listenerList.push(renderListener);
        }
    }

    reSetSize = (event?: any) => {
        const containerEle = document.getElementById('map-utils-container');
        if (containerEle) {
            // 首次渲染完成后，map.getSize偏大，计算工具箱高度时减去160px
            setTimeout(() => {
                // containerEle.style.height = document.getElementById('map').clientHeight - (this.renderFirst ? 160 : 80) + 'px';
                containerEle.style.height = this.map.getSize()[1] - 80 + 'px';
                // 重置 工具组 高度，以计算是否滚动
                const listEle = containerEle.getElementsByClassName('map-utils-list')[0];
                const contentEle = containerEle.getElementsByClassName('content-wrapper')[0];
                if (listEle) { // 44 是title高度
                    (listEle as any).style.height = (containerEle.clientHeight - 44) + 'px';
                }
                if (contentEle) {
                    (contentEle as any).style.height = (containerEle.clientHeight - 44) + 'px';
                }
                if (this.renderFirst) {
                    this.renderFirst = false;
                }
            }, 0);
        }
    }

    toggleUtilsVisible() {
        if (this.utilsVisible) {
            this.closeUtilsBox();
        } else {
            this.utilsVisible = true;
            setTimeout(() => {
                this.reSetSize();
            }, 0)
        }
    }

    backUtilsBox() {
        this.cancelUtil();
    }

    cancelUtil() {
        const util = this.currentUtil;
        if (util && util.isOpen) {
            this.utilHost.viewContainerRef.detach();
            if (util.isAlways) {
                util.isOpen = false;
                this.currentUtil = void 0;
            } else {
                (<UtilComponent>util.componentRef.instance).cancel();
                util.isOpen = false;
                util.componentRef.destroy();
                util.componentRef = void 0;
                this.currentUtil = void 0;
            }
        }
    }

    insertUtilContent(util: any, data?: any) {
        const viewContainerRef = this.utilHost.viewContainerRef;
        if (util.isAlways && util.componentRef) {
            viewContainerRef.insert(util.viewRef);

            util.isOpen = true; // 当前功能正显示在页面 或 常驻功能处于打开状态
            util.switch = util.switch || false;
            this.currentUtil = util;
        } else {
            const componentFactory = this.componentFactoryResolver.resolveComponentFactory(util.component);
            viewContainerRef.clear();
            const currentComponentRef = viewContainerRef.createComponent(componentFactory);
            (<InteractionCompnent>currentComponentRef.instance).data = {...util.data, map: this.map, ...data};

            util.componentRef = currentComponentRef;
            util.viewRef = viewContainerRef.get(0);
            util.isOpen = true; // 当前功能正显示在页面 或 常驻功能处于打开状态
            util.toggle = (currentComponentRef.instance as any).toggle;
            util.isAlways = !!util.toggle;
            util.switch = util.switch || false;
            this.currentUtil = util;
        }
    }

    closeUtilsBox() {
        this.utilsVisible = false;
        this.cancelUtil();
    }

    ngOnDestroy(): void {
        this.listenerList.map(item => {
            unByKey(item);
        });
    }

    toggle(util: any) {
        util.toggle(util.switch);
    }
}

